package Example3 where

import Vector

interface (Base :: ((*) -> *) -> ((*) -> *) -> (*) -> (*) -> ((#) -> *) -> (*) -> (*) -> ((#) -> *) -> *) a b c d e f g h = {
  inner :: ()
 }
 deriving (DefaultValue, Bits)

interface (Wrapper :: (*) -> *) t = {
  inner :: t
 }
 deriving (DefaultValue, Bits)

type Wrapped a b c d e f g h = Wrapper (Base a b c d e f g h)

interface (AB :: (*) -> *) t = {
  inner :: t
 }
 deriving (DefaultValue)

interface (EH :: (#) -> *) n = {
  inner :: Bit n
 }
 deriving (DefaultValue)

type Specify0 t = t Bool Bool EH Bool Bool EH
type Specify1 t = Specify0 (t AB AB)

type Specified = Specify1 Wrapped

interface Dut = {
  input  :: Specified -> Action {-# always_ready, always_enabled #-};
  output :: Specified
}

mkDut :: (IsModule m c) => m Dut
mkDut = module
  inWire :: Wire Specified
  inWire <- mkDWire defaultValue

  interface Dut
    input s = do
      inWire := s
    output = inWire
